// Fill out your copyright notice in the Description page of Project Settings.



#include "UI/Widget/SSlateDemoSlateAdvancedWidget.h"
#include "SlateOptMacros.h"
#include "Widgets/Layout/SScrollBox.h"
#include "Widgets/Layout/SGridPanel.h"
#include "Widgets/Input/SSpinBox.h"
#include "Widgets/Input/SEditableTextBox.h"
#include "Widgets/Text/STextBlock.h"
#include "AppFramework/Public/Widgets/Colors/SColorPicker.h"
#include "Widgets/Colors/SColorBlock.h"
#include "Misc/MessageDialog.h"
#include "FTestData.h"
#include "FCustomDetailCategory.h"
#include "Widgets/Views/STreeView.h"
#include <TreeItemData.h>
#include "Widgets/Layout/SSpacer.h"
#include "Widgets/Input/SCheckBox.h"
#include "Widgets/SOverlay.h"
#include "Framework/Commands/UIAction.h"
#include "UI/Style/SlateDemoManager.h"
#include "UI/Style/SlateDemoWidgetStyle.h"
#include "SlateDemoDetails.h"
#include "Widgets/Layout/SConstraintCanvas.h"
#include "IDetailsView.h"
#include "XmlParser/Public/XmlFile.h"
#include "../Private/PackageReader.h"
#include "AssetData.h"
#include <Widgets/SViewport.h>
#include <IVREditorModule.h>

//Mytree
#include "UI/MyTree/SMyTreeView.h"
#include "UI/MyTree/SMyTableViewBase.h"


BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SSlateDemoSlateAdvancedWidget::Construct(const FArguments& InArgs)
{
	FDetailsViewArgs DetailsViewArgs(false, false, false, FDetailsViewArgs::HideNameArea);
	myDetailObject = GetMutableDefault<USlateDemoDetails>();
	TSharedPtr<IDetailsView> DetailsView = FModuleManager::GetModuleChecked<FPropertyEditorModule>("PropertyEditor").CreateDetailView(DetailsViewArgs);
	DetailsView->SetObject(myDetailObject);

	myDetailObject->a = 666;
	ToolbarStyle = &SlateDemoManager::Get().GetWidgetStyle<FSlateDemoStyle>("SlateDemoStyle_BP");
	DataInit();
	ChildSlot
	[
		SNew(SScrollBox)
		+SScrollBox::Slot()
		[
			MakeMainMenu()
		]
		+ SScrollBox::Slot()
		.Padding(5.0f)
		[
			SNew(SGridPanel)
			.FillColumn(0, 0.1f)
			.FillColumn(1, 0.9f)
#pragma region SColorPicker(颜色选择窗口)
			+SGridPanel::Slot(0,0)
			[
				SNew(STextBlock)
				.Text(FText::FromString(TEXT("SColorPicker")))
			.ToolTipText(FText::FromString(TEXT("颜色选择")))
			]
			+ SGridPanel::Slot(1, 0)
			[
				SNew(SHorizontalBox)
				+SHorizontalBox::Slot()
				.AutoWidth()
				[
					SNew(SVerticalBox)

					+ SVerticalBox::Slot().AutoHeight()
					[
						SNew(SButton)
						.Text( FText::FromString(TEXT( "带透明通道的颜色编辑器") ))
						.ContentPadding( 5 )
						.OnClicked( this, &SSlateDemoSlateAdvancedWidget::OpenColorPicker )
					]
					+ SVerticalBox::Slot().AutoHeight()
					[
						SNew(SBox).HeightOverride(100)
						[
							SNew(SColorBlock).Color_Lambda([this](){
								return this->UseAlphaColor.Get();
							})
						]
					]
					+ SVerticalBox::Slot().AutoHeight()
					[
						SNew(STextBlock).Text_Lambda([this](){
							return FText::FromString(UseAlphaColor.Get().ToFColor(false).ToString());
						})
					]
					
				]
				+SHorizontalBox::Slot()
				.AutoWidth()
				[
					SNew(SVerticalBox)
					+ SVerticalBox::Slot().AutoHeight()
					[
						SNew(SButton)
							.Text( FText::FromString(TEXT("不带透明通道的颜色编辑器") ))
							.ContentPadding( 5 )
							.OnClicked( this, &SSlateDemoSlateAdvancedWidget::OpenColorPickerNoAlpha )
					]
					+ SVerticalBox::Slot().AutoHeight()
					[
						SNew(SBox).HeightOverride(100)
						[
							SNew(SColorBlock).Color_Lambda([this](){
								return this->NotUseAlphaColor.Get();
							})
						]
					]
					+ SVerticalBox::Slot().AutoHeight()
					[
						SNew(STextBlock).Text_Lambda([this](){
							return FText::FromString(NotUseAlphaColor.Get().ToFColor(false).ToString());
						})
					]
				]
			]
#pragma endregion
#pragma region FMessageDialog(询问窗口)
			+ SGridPanel::Slot(0, 1)
				[
					SNew(STextBlock)
					.Text(FText::FromString(TEXT("FMessageDialog")))
					.ToolTipText(FText::FromString(TEXT("对话框窗口")))
				]
			+ SGridPanel::Slot(1, 1)
				[
					SNew(SBox).WidthOverride(100)
					[
						SNew(SButton).Text(FText::FromString(TEXT("弹出窗口"))).OnClicked_Lambda([](){
							if (FMessageDialog::Open(EAppMsgType::YesNo, FText::FromString(TEXT("这是提示窗口"))) != EAppReturnType::Yes)//这个弹出窗口会收到编辑器的风格影响
							{
								return FReply::Handled();
							}
							return FReply::Handled();
						})
					]
				]
#pragma endregion
#pragma region SListView(列表)
			+ SGridPanel::Slot(0, 3)
				[
					SNew(STextBlock)
					.Text(FText::FromString(TEXT("SListView")))
					.ToolTipText(FText::FromString(TEXT("列表")))
				]
			+ SGridPanel::Slot(1, 3)
				[
					SNew(SHorizontalBox)
					+ SHorizontalBox::Slot().AutoWidth()
					.Padding(0.0f, 5.0f, 0.0f, 0.0f)
				[
					SNew(SListView<TSharedPtr<FString>>)
					.ItemHeight(16.0f)
					.ListItemsSource(&SListViewFString)
					.OnGenerateRow(this, &SSlateDemoSlateAdvancedWidget::GenerateComboItem)
					.SelectionMode(ESelectionMode::None)
				]

			+ SHorizontalBox::Slot().AutoWidth()
				.Padding(100.0f, 5.0f, 0.0f, 0.0f)
				[
					SNew(SListView<TSharedPtr<FString>>)
					.ItemHeight(16.0f)
					.ListItemsSource(&SListViewFString)
					.OnGenerateRow(this, &SSlateDemoSlateAdvancedWidget::HandleMapListViewGenerateRow)
					.SelectionMode(ESelectionMode::None)
				]

			+ SHorizontalBox::Slot().AutoWidth()
				.Padding(100.0f, 5.0f, 0.0f, 0.0f)
				[
					SNew(SBox).WidthOverride(500).HeightOverride(200)
					[
						// The list view being tested
						SAssignNew(ListBeingTested, SListView< TSharedPtr<FTestData> >)
						//.ExternalScrollbar( ExternalScrollbar )
						// List view items are this tall
						.ItemHeight(24)
						// Tell the list view where to get its source data
						.ListItemsSource(&Items)//资源放到这里了
						// When the list view needs to generate a widget for some data item, use this method
						.OnGenerateRow(this, &SSlateDemoSlateAdvancedWidget::OnGenerateWidgetForList)//每行的展现方式，在这里可以自定义样式
						// What to put in the context menu
						.OnContextMenuOpening(this, &SSlateDemoSlateAdvancedWidget::GetListContextMenu)//上下文菜单

						.WheelScrollMultiplier(60.f)
						// Single, multi or no selection
						.SelectionMode(ESelectionMode::Single)
						.HeaderRow
						(
							SNew(SHeaderRow)
							+ SHeaderRow::Column("Name").DefaultLabel(FText::FromString(TEXT("Name")))
							+ SHeaderRow::Column("Number").DefaultLabel(FText::FromString(TEXT("Number")))
							+ SHeaderRow::Column("TextField").DefaultLabel(FText::FromString(TEXT("Text Field")))
							+ SHeaderRow::Column("TextBlock").DefaultLabel(FText::FromString(TEXT("Text Block")))
							+ SHeaderRow::Column("AddChild").DefaultLabel(FText::FromString(TEXT("Add Child")))
						)
					]

				]
				]
#pragma endregion
#pragma region STreeView(树形列表)
			+ SGridPanel::Slot(0, 4)
				[
					SNew(STextBlock)
					.Text(FText::FromString(TEXT("STreeView")))
					.ToolTipText(FText::FromString(TEXT("树列表")))
				]
			+ SGridPanel::Slot(1, 4)
				[
					SNew(SHorizontalBox)

					+SHorizontalBox::Slot().AutoWidth()
					[
						SNew(STreeView<TSharedPtr<FTreeItemData>>)
						//.ItemHeight(TreeViewStyle->CheckBoxHeight)
						.SelectionMode(ESelectionMode::Single)
						.TreeItemsSource(&TreeData)
						.OnGenerateRow(this, &SSlateDemoSlateAdvancedWidget::BuildRow)
						.OnGetChildren(this, &SSlateDemoSlateAdvancedWidget::OnGetChildren)
			/*	.HeaderRow
				(
					SNew(SHeaderRow)
					+ SHeaderRow::Column("Name").DefaultLabel(FText::FromString(TEXT("Name")))
					+ SHeaderRow::Column("Number").DefaultLabel(FText::FromString(TEXT("Number")))
				)*/
					]
					+SHorizontalBox::Slot().AutoWidth().Padding(100.0f, 5.0f, 0.0f, 0.0f)
					[
						SNew(SBox).WidthOverride(500).HeightOverride(600)
						[
							SNew(SBorder).BorderImage(FCoreStyle::Get().GetBrush("ToolPanel.GroupBorder"))
							[
								// The TreeView being tested; mostly identical to ListView except for OnGetChildren
								SAssignNew(TreeBeingTested, STreeView< TSharedPtr<FTestData> >)
								.ItemHeight(24)
								.TreeItemsSource(&Items)
								.OnGenerateRow(this, &SSlateDemoSlateAdvancedWidget::OnGenerateWidgetForTree)
								// Given some DataItem, this is how we find out if it has any children and what they are.
								.OnGetChildren(this, &SSlateDemoSlateAdvancedWidget::OnGetChildrenForTree)
								// What to put in the context menu
								.OnContextMenuOpening(this, &SSlateDemoSlateAdvancedWidget::GetTreeContextMenu)
								.WheelScrollMultiplier(60.f)
						.HeaderRow
						(
							SNew(SHeaderRow)
							+ SHeaderRow::Column("Name").DefaultLabel(FText::FromString(TEXT("Name")))
							+ SHeaderRow::Column("Number").DefaultLabel(FText::FromString(TEXT("Number")))
							+ SHeaderRow::Column("TextField").DefaultLabel(FText::FromString(TEXT("Text Field")))
							+ SHeaderRow::Column("TextBlock").DefaultLabel(FText::FromString(TEXT("Text Block")))
							+ SHeaderRow::Column("AddChild").DefaultLabel(FText::FromString(TEXT("Add Child")))
						)
							]
						]
					]
					+ SHorizontalBox::Slot().AutoWidth().Padding(100.0f, 5.0f, 0.0f, 0.0f)
					[
						SNew(STextBlock)
						.Text(FText::FromString(TEXT("从源码中摘出的树,以便修改树的UI")))
					]
					+ SHorizontalBox::Slot().AutoWidth().Padding(10.0f, 5.0f, 0.0f, 0.0f)
					[
						SNew(MyTree::STreeView<TSharedPtr<FTreeItemData>>)
						//.ItemHeight(TreeViewStyle->CheckBoxHeight)
						.SelectionMode(ESelectionMode::Single)
						.TreeItemsSource(&TreeData)
						.OnGenerateRow(this, &SSlateDemoSlateAdvancedWidget::BuildRow_MyTree)
						.OnGetChildren(this, &SSlateDemoSlateAdvancedWidget::OnGetChildren)
						.HeaderRow
						(
							SNew(MyTree::SHeaderRow)
							+ MyTree::SHeaderRow::Column("Name").DefaultLabel(FText::FromString(TEXT("Name")))
							+ MyTree::SHeaderRow::Column("Number").DefaultLabel(FText::FromString(TEXT("Number")))
						)
					]
				]
#pragma endregion
#pragma region PropertyEditorModule(属性编辑模块)
			+ SGridPanel::Slot(0, 5)
				[
					SNew(SHorizontalBox)

					+SHorizontalBox::Slot().AutoWidth().VAlign(VAlign_Top)
					[
						SNew(SBox).WidthOverride(20).HeightOverride(20)
						[
							SNew(SImage).Image(&ToolbarStyle->WarningIco)
						]
					]
					+ SHorizontalBox::Slot().AutoWidth()
					[
						SNew(STextBlock)
						.Text(FText::FromString(TEXT("PropertyEditorModule(警告)"))).ColorAndOpacity(FLinearColor(1.f,0.f,0.f))
						.ToolTipText(FText::FromString(TEXT("属性编辑模块 这个功能再独立程序中可以忽视,因为只有再UE4编译环境下才可使用,使用此功能需要依赖UEditorEngine,此对象只有再UE4环境下才初始化")))
					]
				]
			+ SGridPanel::Slot(1, 5)
				[
					SNew(SConstraintCanvas)
					+ SConstraintCanvas::Slot()
					.Anchors(FAnchors(0.0, 0.0, 0.0, 0.0))
					.Alignment(FVector2D(0.0, 0.0))
					.Offset(FMargin(0, 0, 300, 500))
					[
						DetailsView->AsShared()
					]
				]
#pragma endregion
#pragma region CustomDetailCategory(自定义的属性列表)
			+ SGridPanel::Slot(0, 6)
				[
					SNew(STextBlock)
					.Text(FText::FromString(TEXT("CustomDetailCategory")))
					.ToolTipText(FText::FromString(TEXT("自定义的属性列表")))
				]
			+ SGridPanel::Slot(1, 6)
				[
					SNew(SConstraintCanvas)
					+ SConstraintCanvas::Slot()
					.Anchors(FAnchors(0.0, 0.0, 0.0, 0.0))
					.Alignment(FVector2D(0.0, 0.0))
					.Offset(FMargin(0, 0, 300, 1600))
					[
						SAssignNew(Treeview, STreeView< TSharedPtr<FCustomDetailCategoryData> >)
						//.ExternalScrollbar( ExternalScrollbar )
						// List view items are this tall
					.ItemHeight(24)
					// Tell the list view where to get its source data
					.TreeItemsSource(&CustomDetailCategoryItems)//资源放到这里了
					// When the list view needs to generate a widget for some data item, use this method
					.OnGetChildren(this, &SSlateDemoSlateAdvancedWidget::OnGetChildrenForTree_CustomDetailCategory)
					.OnGenerateRow(this, &SSlateDemoSlateAdvancedWidget::OnGenerateWidgetForTree_CustomDetailCategory)
					// What to put in the context menu
					//.OnContextMenuOpening(this, &SSlateDemoSlateAdvancedWidget::GetListContextMenu)//上下文菜单

					.WheelScrollMultiplier(60.f)
					// Single, multi or no selection
					.SelectionMode(ESelectionMode::None)
					.HeaderRow
					(
						SNew(SHeaderRow)
						+ SHeaderRow::Column("Key").DefaultLabel(FText::FromString(TEXT("属性")))
						.FillWidth(0.40f)
						+ SHeaderRow::Column("Value").DefaultLabel(FText::FromString(TEXT("值")))
						.FillWidth(0.60f)
					)
					]
				]
#pragma endregion
		]
	];
	/*for (auto CurItemIndex = 0; CurItemIndex < CustomDetailCategoryItems.Num(); ++CurItemIndex)
	{
		Treeview->SetItemExpansion(CustomDetailCategoryItems[CurItemIndex], true);
	}*/
	TreeExpansion(CustomDetailCategoryItems, true);
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SSlateDemoSlateAdvancedWidget::TreeExpansion(TArray< TSharedPtr< FCustomDetailCategoryData > > Tree, bool IsExpansion)//将树全展开或者全闭合
{
	for (auto CurItemIndex = 0; CurItemIndex < Tree.Num(); ++CurItemIndex)
	{
		Treeview->SetItemExpansion(Tree[CurItemIndex], IsExpansion);
		//向下遍历对分支进行操作
		TArray< TSharedPtr< FCustomDetailCategoryData > > Children;
		Tree[CurItemIndex]->GetChildren(Children);
		if(Children.Num() > 0)
			TreeExpansion(Children,IsExpansion);
	}
}

TSharedRef<FCustomDetailCategoryData> SSlateDemoSlateAdvancedWidget::MakeTree(TSharedPtr<FTreeNode> Treenode, DataType dataytpe)//创建一颗树
{
	if (dataytpe == DataType::FirstTree || dataytpe == DataType::Title)//在根节点的情况下进行遍历
	{
		TSharedRef<FCustomDetailCategoryData> Node =
			FCustomDetailCategoryData::Make(
				FText::FromString(Treenode->GetKey()),
				FText::FromString(""),
				dataytpe);

		for (auto tnode : Treenode->GetNodes())
		{
			TSharedRef<FCustomDetailCategoryData> ChildNode = FCustomDetailCategoryData::Make(FText::FromString(""), FText::FromString(""), DataType::Data);;
			if (!tnode->GetValue().Compare(""))//当前节点没有值则代表是跟结点
			{
				if (dataytpe == DataType::Title)
				{
					ChildNode = MakeTree(tnode, DataType::FirstTree);//向下遍历
				}
			}
			else
			{//子结点
				if (dataytpe == DataType::Title)
				{
					ChildNode = FCustomDetailCategoryData::Make(FText::FromString(tnode->GetKey()), FText::FromString(tnode->GetValue()), DataType::Data);
				}
				else if (dataytpe == DataType::FirstTree)//当前结点是一级分支对应的子结点是
				{
					ChildNode = FCustomDetailCategoryData::Make(FText::FromString(tnode->GetKey()), FText::FromString(tnode->GetValue()), DataType::FirstTreeData);
				}
			}
			Node->AddChild(ChildNode);
		}
		return Node;
	}
	else
		return FCustomDetailCategoryData::Make(FText::FromString(Treenode->GetKey()), FText::FromString(Treenode->GetValue()), DataType::Data);
}

void SSlateDemoSlateAdvancedWidget::DataInit()//数据初始化
{

	UseAlphaColor = FLinearColor(0.f, 1.f, 0.f);
	NotUseAlphaColor = FLinearColor(1.f, 1.f, 0.f);

	Items.Empty();
	SListViewFString.Empty();
	for (int32 ItemIndex = 0; ItemIndex < 20; ++ItemIndex)
	{
		TSharedRef<FTestData> NewItem = FTestData::Make(FText::Format(FText::FromString(TEXT("SListView_{0}")), FText::AsNumber(ItemIndex)));
		Items.Add(NewItem);
		FTestData::GenerateChildren(NewItem, 20, 0);
		SListViewFString.Add(MakeShareable(new FString(TEXT("SListView_") + FString::FromInt(ItemIndex))));
	}

	//加载XML文件填写自定义属性列表
	const FString& InXmlFilePath = TEXT("F:/ue4/SlateDemo/Content/test.xml");
	IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
	if (PlatformFile.FileExists(*InXmlFilePath))
	{
		TSharedPtr<FXmlFile> XmlFile = MakeShareable(new FXmlFile(InXmlFilePath));
		if (XmlFile->IsValid())										// FXmlFile->IsValid()与智能指针的.IsValid()是不同的方法
		{
			FXmlNode* RootNode = XmlFile->GetRootNode();
			if (RootNode != nullptr)//<ArrayOfModel>
			{
				for (FXmlNode* Model : RootNode->GetChildrenNodes())
				{
					if (!Model->GetTag().Compare("Model"))//<Model>
					{
						TreeRootNode = MakeShareable(new FTreeNode("Root", ""));
						for (FXmlNode* FirstNode : Model->GetChildrenNodes())//第一层遍历 实例参数和类型参数    <InstanceProperties>      
						{
							if (FirstNode->GetChildrenNodes().Num() != 0) {
								TSharedRef<FTreeNode> NewFirstNode = MakeShareable(new FTreeNode(FirstNode->GetTag(), ""));
								for (FXmlNode* FirstCHildNode : FirstNode->GetChildrenNodes())//第二层遍历 族 <ParameterGroup>
								{
									if (FirstCHildNode->GetChildrenNodes().Num() != 0) {
										TSharedRef<FTreeNode> NewSecondNode = MakeShareable(new FTreeNode("", ""));
										for (FXmlNode* TwoCHildNode : FirstCHildNode->GetChildrenNodes())//第三次遍历  内的每个参数
										{
											if (!TwoCHildNode->GetTag().Compare("Infos")) //< Infos >
											{
												for (FXmlNode* InfoNode : TwoCHildNode->GetChildrenNodes())//第三次遍历  内的每个参数
												{
													FString Key;
													FString Value;
													for (FXmlNode* ThreeCHildNode : InfoNode->GetChildrenNodes())
													{
														if (!ThreeCHildNode->GetTag().Compare("Name"))
														{
															Key = ThreeCHildNode->GetContent();
														}
														else
														{
															Value.Append(FString::Format(TEXT("{0}:{1}  "), { ThreeCHildNode->GetTag(), ThreeCHildNode->GetContent() }));
														}
													}
													TSharedRef<FTreeNode> ThreeCHildNode = MakeShareable(new FTreeNode(Key, Value));
													NewSecondNode->AddNode(ThreeCHildNode);
												}
											}
											else if (!TwoCHildNode->GetTag().Compare("ParameterGrop")) {//<ParameterGrop>
												NewSecondNode->SetKey(TwoCHildNode->GetContent());
											}
										}
										NewFirstNode->AddNode(NewSecondNode);
									}
								}
								TreeRootNode->AddNode(NewFirstNode);
							}
						}
					}
				}
			}
		}
	}



	//自定义树的生成
	CustomDetailCategoryItems.Empty();
	for (int ItemIndex = 0; ItemIndex < TreeRootNode->GetNodes().Num(); ItemIndex++)
	{
		CustomDetailCategoryItems.Add(MakeTree(TreeRootNode->GetNodes()[ItemIndex], DataType::Title));
	}

	/*for (int32 ItemIndex = 0; ItemIndex < 5; ++ItemIndex)
	{
		TSharedRef<FCustomDetailCategoryData> NewItem = FCustomDetailCategoryData::Make(FText::Format(FText::FromString(TEXT("SListView_{0}")), FText::AsNumber(ItemIndex)), FText::FromString(""), DataType::Title);
		CustomDetailCategoryItems.Add(NewItem);
		FCustomDetailCategoryData::GenerateChildren(NewItem, 1, 0);
	}*/

	TreeData.Empty();
	TSharedPtr<FTreeItemData> A = MakeShareable(new FTreeItemData(0, TEXT("一级_建筑")));
	TSharedPtr<FTreeItemData> S = MakeShareable(new FTreeItemData(1, TEXT("二级_结构")));
	A->AddNode(S);
	TSharedPtr<FTreeItemData> P = MakeShareable(new FTreeItemData(2, TEXT("三级_给排水")));
	S->AddNode(P);
	P->AddNode(MakeShareable(new FTreeItemData(1, TEXT("暖通1"))));
	P->AddNode(MakeShareable(new FTreeItemData(1, TEXT("暖通2"))));
	P->AddNode(MakeShareable(new FTreeItemData(1, TEXT("暖通3"))));
	TreeData.Add(A);
	TreeData.Add(MakeShareable(new FTreeItemData(0, TEXT("电气"))));


	

}

FReply SSlateDemoSlateAdvancedWidget::OpenColorPicker()
{
	TSharedRef<SWindow> NewSlateWindow = FSlateApplication::Get().AddWindow(
		SNew(SWindow)
		.Title(FText::FromString(TEXT("Standard Color")))
		.ClientSize(SColorPicker::DEFAULT_WINDOW_SIZE)
	);

	TSharedPtr<SColorPicker> ColorPicker = SNew(SColorPicker)
		.TargetColorAttribute(this, &SSlateDemoSlateAdvancedWidget::GetColor, UseAlphaColor)
		.OnColorCommitted(this, &SSlateDemoSlateAdvancedWidget::AlphaUpdateColor)
		.ParentWindow(NewSlateWindow);

	NewSlateWindow->SetContent(ColorPicker.ToSharedRef());

	return FReply::Handled();
}

FReply SSlateDemoSlateAdvancedWidget::OpenColorPickerNoAlpha()
{
	TSharedRef<SWindow> NewSlateWindow = FSlateApplication::Get().AddWindow(
		SNew(SWindow)
		.Title(FText::FromString(TEXT("No Alpha Color")))
		.ClientSize(SColorPicker::DEFAULT_WINDOW_SIZE)
	);

	TSharedPtr<SColorPicker> ColorPicker = SNew(SColorPicker)
		.UseAlpha(false)//没有透明通道
		.TargetColorAttribute(this, &SSlateDemoSlateAdvancedWidget::GetColor,NotUseAlphaColor)
		.OnColorCommitted(this, &SSlateDemoSlateAdvancedWidget::UpdateColor)
		.ParentWindow(NewSlateWindow);

	NewSlateWindow->SetContent(ColorPicker.ToSharedRef());

	return FReply::Handled();
}
FLinearColor SSlateDemoSlateAdvancedWidget::GetColor(TAttribute<FLinearColor> FlColor) const
{
	return FlColor.Get();
}

void SSlateDemoSlateAdvancedWidget::UpdateColor(FLinearColor NewColor)
{

	NotUseAlphaColor.Set(NewColor);
	//OutputTextBlock->SetText(FText::FromString(Color.Get().ToFColor(false).ToString()));
}
void SSlateDemoSlateAdvancedWidget::AlphaUpdateColor(FLinearColor NewColor)
{

	UseAlphaColor.Set(NewColor);
	//OutputTextBlock->SetText(FText::FromString(Color.Get().ToFColor(false).ToString()));
}


TSharedRef<ITableRow> SSlateDemoSlateAdvancedWidget::GenerateComboItem(TSharedPtr<FString> InItem, const TSharedRef<STableViewBase>& OwnerTable)
{
	return SNew(STableRow<TSharedPtr<FString>>, OwnerTable)
		[
			SNew(STextBlock).Text(FText::FromString(*InItem))
		];
}

TSharedRef<ITableRow> SSlateDemoSlateAdvancedWidget::HandleMapListViewGenerateRow(TSharedPtr<FString> InItem, const TSharedRef<STableViewBase>& OwnerTable)
{
	return
		SNew(STableRow<TSharedPtr<FString>>, OwnerTable)
		[
			SNew(SCheckBox)
			.Padding(FMargin(6.0, 2.0))
		[
			SNew(STextBlock)
			.Text(FText::FromString(*InItem))
		]
		];
}
TSharedRef<ITableRow> SSlateDemoSlateAdvancedWidget::OnGenerateWidgetForList(TSharedPtr<FTestData> InItem, const TSharedRef<STableViewBase>& OwnerTable)
{
	return
		SNew(SItemEditor, OwnerTable)
		// Triggered when a user is attempting to drag, so initiate a DragDropOperation.
		.OnDragDetected(this, &SSlateDemoSlateAdvancedWidget::OnDragDetected_Handler, TWeakPtr<FTestData>(InItem))//让选项可以拖拽,从而改变顺序

		// Given a hovered drop zone (above, onto, or below) respond with a zone where we would actually drop the item.
		// Respond with an un-set TOptional<EItemDropZone> if we cannot drop here at all.
		.OnCanAcceptDrop(this, &SSlateDemoSlateAdvancedWidget::OnCanAcceptDrop_Handler)//判断是否可以执行下落操作
		// Actually perform the drop into the given drop zone.
		.OnAcceptDrop(this, &SSlateDemoSlateAdvancedWidget::OnAcceptDrop_Handler)//执行下落操作

		.ItemToEdit(InItem);
}
FReply SSlateDemoSlateAdvancedWidget::OnDragDetected_Handler(const FGeometry&, const FPointerEvent&, TWeakPtr<FTestData> TestData)
{
	return FReply::Handled().BeginDragDrop(FTableViewDragDrop::New(TestData.Pin().ToSharedRef()));
}
TOptional<EItemDropZone> SSlateDemoSlateAdvancedWidget::OnCanAcceptDrop_Handler(const FDragDropEvent& DragDropEvent, EItemDropZone DropZone, TSharedPtr<FTestData> TargetItem)
{
	TSharedPtr<FTableViewDragDrop> DragDropOperation = DragDropEvent.GetOperationAs<FTableViewDragDrop>();
	if (DragDropOperation.IsValid())
	{
		return DropZone;
	}
	else
	{
		return TOptional<EItemDropZone>();
	}
}


FReply SSlateDemoSlateAdvancedWidget::OnAcceptDrop_Handler(const FDragDropEvent& DragDropEvent, EItemDropZone DropZone, TSharedPtr<FTestData> TargetItem)
{
	TSharedPtr<FTableViewDragDrop> DragDropOperation = DragDropEvent.GetOperationAs<FTableViewDragDrop>();
	if (DragDropOperation.IsValid())
	{
		const TSharedRef<FTestData>& ItemBeingDragged = DragDropOperation->GetDraggedItem();
		FTestData::RemoveRecursive(Items, ItemBeingDragged);
		FTestData::InsertRecursive(Items, ItemBeingDragged, TargetItem.ToSharedRef(), DropZone);
		ListBeingTested->RequestListRefresh();
		TreeBeingTested->RequestTreeRefresh();
		/*	HorizontalListBeingTested->RequestListRefresh();
			TileViewBeingTested->RequestListRefresh();
			HorizontalTileViewBeingTested->RequestListRefresh();*/

		return FReply::Handled();
	}
	else
	{
		return FReply::Unhandled();
	}
}

TSharedPtr<SWidget> SSlateDemoSlateAdvancedWidget::GetListContextMenu()
{
	return
		SNew(SVerticalBox)
		+ SVerticalBox::Slot()
		.AutoHeight()
		[
			SNew(SBorder)
			.BorderImage(FCoreStyle::Get().GetBrush("Menu.Background"))
		.Padding(FMargin(5))
		[
			SNew(STextBlock).Text(FText::FromString(TEXT("List Context Menu")))
		]
		]
	+ SVerticalBox::Slot()
		.AutoHeight()
		[
			SNew(STestMenu)
		];

}

TSharedRef<ITableRow> SSlateDemoSlateAdvancedWidget::BuildRow(TSharedPtr<FTreeItemData> InItem, const TSharedRef<STableViewBase>& OwnerTable)
{
	if (!InItem.IsValid())
	{
		return SNew(STableRow<TSharedPtr<FTreeItemData>>, OwnerTable)
			[
				SNew(STextBlock)
				.Text(FText::FromString("THIS WAS NULL SOMEHOW"))
			];
	}

	return SNew(STableRow<TSharedPtr<FTreeItemData>>, OwnerTable)
		[
			SAssignNew(InItem->UINode,SCheckBox)
			.IsChecked(false)
			.OnCheckStateChanged_Lambda([InItem](ECheckBoxState CheckState) {
				InItem->CheckStateChange(CheckState);
			})
			.Padding(FMargin(6.0, 2.0))
			[
				SNew(STextBlock)
				.Text(FText::FromString(InItem->GetName()))
			]
			/*SNew(SHorizontalBox)
			+ SHorizontalBox::Slot() 
			.FillWidth(1.f)
			[
				SNew(SBox)
				.VAlign(VAlign_Center)
				[
					SNew(STextBlock)
					.Text(FText::FromString(InItem->GetName()))
				]
			]*/
		];
}

TSharedRef<MyTree::ITableRow> SSlateDemoSlateAdvancedWidget::BuildRow_MyTree(TSharedPtr<FTreeItemData> InItem, const TSharedRef<MyTree::STableViewBase>& OwnerTable)
{
	if (!InItem.IsValid())
	{
		return SNew(MyTree::STableRow<TSharedPtr<FTreeItemData>>, OwnerTable)
			[
				SNew(STextBlock)
				.Text(FText::FromString("THIS WAS NULL SOMEHOW"))
			];
	}

	return SNew(MyTree::STableRow<TSharedPtr<FTreeItemData>>, OwnerTable)
		[
			SAssignNew(InItem->UINode, SCheckBox)
			.IsChecked(false)
		.OnCheckStateChanged_Lambda([InItem](ECheckBoxState CheckState) {
		InItem->CheckStateChange(CheckState);
			})
		.Padding(FMargin(6.0, 2.0))
				[
					SNew(STextBlock)
					.Text(FText::FromString(InItem->GetName()))
				]
			/*SNew(SHorizontalBox)
			+ SHorizontalBox::Slot()
			.FillWidth(1.f)
			[
				SNew(SBox)
				.VAlign(VAlign_Center)
				[
					SNew(STextBlock)
					.Text(FText::FromString(InItem->GetName()))
				]
			]*/
		];
}

void SSlateDemoSlateAdvancedWidget::OnGetChildren(TSharedPtr<FTreeItemData> InItem, TArray<TSharedPtr<FTreeItemData>>& OutChildren)
{
	const auto& NodePtrs = InItem->GetNodes();
	return OutChildren.Append(NodePtrs);
}

TSharedRef<ITableRow> SSlateDemoSlateAdvancedWidget::OnGenerateWidgetForTree(TSharedPtr<FTestData> InItem, const TSharedRef<STableViewBase>& OwnerTable)
{
	return
		SNew(SItemEditor, OwnerTable)
		.OnCanAcceptDrop(this, &SSlateDemoSlateAdvancedWidget::OnCanAcceptDrop_Handler)
		.OnAcceptDrop(this, &SSlateDemoSlateAdvancedWidget::OnAcceptDrop_Handler)
		.OnDragDetected(this, &SSlateDemoSlateAdvancedWidget::OnDragDetected_Handler, TWeakPtr<FTestData>(InItem))
		.ItemToEdit(InItem);
}

void SSlateDemoSlateAdvancedWidget::OnGetChildrenForTree(TSharedPtr< FTestData > InItem, TArray< TSharedPtr<FTestData> >& OutChildren)
{
	InItem->GetChildren(OutChildren);
}

TSharedPtr<SWidget> SSlateDemoSlateAdvancedWidget::GetTreeContextMenu()
{
	return
		SNew(SVerticalBox)
		+ SVerticalBox::Slot()
		.AutoHeight()
		[
			SNew(SBorder)
			.BorderImage(FCoreStyle::Get().GetBrush("Menu.Background"))
		.Padding(FMargin(5))
		[
			SNew(STextBlock).Text(FText::FromString(TEXT("Tree Context Menu")))
		]
		]
	+ SVerticalBox::Slot()
		.AutoHeight()
		[
			SNew(STestMenu)
		];
}

TSharedRef< SWidget > SSlateDemoSlateAdvancedWidget::MakeMainMenu()
{
	FMenuBarBuilder MenuBuilder(nullptr);
	{
		// File
		MenuBuilder.AddPullDownMenu(
			FText::FromString(TEXT("File")),
			FText::FromString(TEXT("Opens the file menu")),
			FNewMenuDelegate::CreateSP(this, &SSlateDemoSlateAdvancedWidget::FillFileMenu));

		// Actions
		MenuBuilder.AddPullDownMenu(
			FText::FromString(TEXT("Actions")),
			FText::FromString(TEXT("Opens the actions menu")),
			FNewMenuDelegate::CreateSP(this, &SSlateDemoSlateAdvancedWidget::FillActionsMenu));

		// Options
		MenuBuilder.AddPullDownMenu(
			FText::FromString(TEXT("Options")),
			FText::FromString(TEXT("Opens the options menu")),
			FNewMenuDelegate::CreateSP(this, &SSlateDemoSlateAdvancedWidget::FillOptionsMenu));
	}

	// Create the menu bar
	TSharedRef< SWidget > MenuBarWidget = MenuBuilder.MakeWidget();

	return MenuBarWidget;
}

void SSlateDemoSlateAdvancedWidget::FillFileMenu(FMenuBuilder& MenuBuilder)
{
	MenuBuilder.BeginSection("File", FText::FromString(TEXT("File")));
	{
		MenuBuilder.AddMenuEntry(
			FText::FromString(TEXT("New...")),
			FText::FromString(TEXT("Creates a new layer and opens the stage with it at its root")),
			FSlateIcon(FCoreStyle::Get().GetStyleSetName(), "WidgetReflector.TabIcon"),
			FUIAction(
				FExecuteAction::CreateSP(this, &SSlateDemoSlateAdvancedWidget::OnNew),
				FCanExecuteAction(),
				FIsActionChecked::CreateLambda([] { return true; })
			),
			NAME_None,
			EUserInterfaceActionType::Check
		);

		MenuBuilder.AddMenuEntry(
			FText::FromString(TEXT("Open...")),
			FText::FromString(TEXT("Opens a USD file")),
			FSlateIcon(),
			FUIAction(
				FExecuteAction::CreateSP(this, &SSlateDemoSlateAdvancedWidget::OnNew),
				FCanExecuteAction()
			),
			NAME_None,
			EUserInterfaceActionType::Button
		);

		MenuBuilder.AddMenuEntry(
			FText::FromString(TEXT("Save")),
			FText::FromString(TEXT("Saves the stage")),
			FSlateIcon(FCoreStyle::Get().GetStyleSetName(), "WidgetReflector.TabIcon"),
			FUIAction(
				FExecuteAction::CreateSP(this, &SSlateDemoSlateAdvancedWidget::OnNew),
				FCanExecuteAction()
			),
			NAME_None,
			EUserInterfaceActionType::Button
		);

		MenuBuilder.AddMenuEntry(
			FText::FromString(TEXT("Reload")),
			FText::FromString(TEXT("Reloads the stage from disk")),
			FSlateIcon(),
			FUIAction(
				FExecuteAction::CreateSP(this, &SSlateDemoSlateAdvancedWidget::OnNew),
				FCanExecuteAction()
			),
			NAME_None,
			EUserInterfaceActionType::Button
		);

		MenuBuilder.AddMenuEntry(
			FText::FromString(TEXT("Close")),
			FText::FromString(TEXT("Closes the opened stage")),
			FSlateIcon(),
			FUIAction(
				FExecuteAction::CreateSP(this, &SSlateDemoSlateAdvancedWidget::OnNew),
				FCanExecuteAction()
			),
			NAME_None,
			EUserInterfaceActionType::Button
		);
	}
	MenuBuilder.EndSection();
}
void SSlateDemoSlateAdvancedWidget::FillActionsMenu(FMenuBuilder& MenuBuilder)
{
	MenuBuilder.BeginSection("Actions", FText::FromString(TEXT("Actions")));
	{
		MenuBuilder.AddMenuEntry(
			FText::FromString(TEXT("Import...")),
			FText::FromString(TEXT("Imports the stage as Unreal assets")),
			FSlateIcon(FEditorStyle::GetStyleSetName(), "ClassIcon.PaperTileSet"),
			FUIAction(
				FExecuteAction::CreateSP(this, &SSlateDemoSlateAdvancedWidget::OnNew),
				FCanExecuteAction()
			),
			NAME_None,
			EUserInterfaceActionType::Button
		);
	}
	MenuBuilder.EndSection();
}

void SSlateDemoSlateAdvancedWidget::FillOptionsMenu(FMenuBuilder& MenuBuilder)
{
	MenuBuilder.BeginSection("Options", FText::FromString(TEXT("Options")));
	{
		MenuBuilder.AddSubMenu(
			FText::FromString(TEXT("Payloads")),
			FText::FromString(TEXT("What to do with payloads when initially opening the stage")),
			FNewMenuDelegate::CreateSP(this, &SSlateDemoSlateAdvancedWidget::FillFileMenu));

		MenuBuilder.AddMenuSeparator();

		MenuBuilder.AddSubMenu(//子菜单
			FText::FromString(TEXT("Purposes to load")),
			FText::FromString(TEXT("Only load prims with these specific purposes from the USD stage")),
			FNewMenuDelegate::CreateSP(this, &SSlateDemoSlateAdvancedWidget::FillActionsMenu),
			false,
			FSlateIcon(FEditorStyle::GetStyleSetName(), "ClassIcon.PaperTileSet"),
			false);
	}
	MenuBuilder.EndSection();
}

void SSlateDemoSlateAdvancedWidget::OnNew(){}

TSharedRef<ITableRow> SSlateDemoSlateAdvancedWidget::OnGenerateWidgetForTree_CustomDetailCategory(TSharedPtr<FCustomDetailCategoryData> InItem, const TSharedRef<STableViewBase>& OwnerTable)
{
	return
		SNew(SCustomDetailCategoryItemEditor, OwnerTable)
		.ItemToEdit(InItem);
}

void SSlateDemoSlateAdvancedWidget::OnGetChildrenForTree_CustomDetailCategory(TSharedPtr< FCustomDetailCategoryData > InItem, TArray< TSharedPtr<FCustomDetailCategoryData> >& OutChildren)
{
	InItem->GetChildren(OutChildren);
}
